package org.despair2D.utils.core 
{
	import org.despair2D.debug.Logger;
	import org.despair2D.utils.ITimer;
	
	import org.despair2D.core.ns_despair;
	use namespace ns_despair;
	
	
	/**
	 * @usage  最低间隔 0.03sec
	 */
public class TimerManagerBase implements ITimerManager
{

	
	
	private static const TIMER_PROP:String = 'timerProp_';

	
	
	/**
	 * 定时器总数
	 */
	public function get numTimer() : int
	{
		return m_numTimer;
	}
	
	
	
	/**
	 * 加入定时器
	 * @param	delay
	 * @param	repeatCount
	 * @param   autoRecycle
	 * @param   timerName
	 */
	public function addTimer( delay:Number, repeatCount:int, autoRecycle:Boolean = false, timerName:String = null ) : ITimer
	{
		var tp:TimerProp = new TimerProp()
		
		if ( timerName != null && m_timerMap[ timerName ] )
		{
			Logger.reportError(this, 'addTimer', '定时器名字，重复 !!');
		}
		
		else
		{
			timerName = TIMER_PROP + tp.timerId;
		}
		
		tp.initialize(delay, repeatCount, autoRecycle, timerName);
		tp.m_manager = this;
		m_timerMap[ timerName ] = tp;
		m_numTimer++;
		
		return tp;
	}
	
	
	/**
	 * 移除定时器
	 * @param	timerName
	 */
	public function removeTimer( timerName:String ) : void
	{
		var tp:TimerProp = m_timerMap[ timerName ];
		
		if (tp)
		{
			tp.dispose();
		}
		
		else
		{
			Logger.reportWarning(this, 'removeTimer', '不存在的定时器 (' + timerName + ') !!');
		}
	}
	
	
	/**
	 * 提取定时器
	 * @param	timerName
	 */
	public function retrieveTimer( timerName:String ) : ITimer
	{
		return m_timerMap[ timerName ];
	}


	
	
	//======================
	// Internal
	//======================
	
	
	/**
	 * 更新
	 * @param	deltaTime
	 */
	public function update( deltaTime:Number ) : void
	{
		var l:int, i:int, index:int;
		var tp:TimerProp;
		
		// 插入待加入
		if (m_joiningLength > 0)
		{
			l = m_joiningLength;
			while (--l > -1)
			{
				tp = m_joiningList[l];
				m_runningList[m_runningLength++] = tp;
				tp.m_flags &= ~TimerProp.t_joiningFlag;
				tp.m_flags |= TimerProp.t_runningFlag;
			}
		}
		
		m_joiningList.length = m_joiningLength = 0;
		
		// 推进开始
		m_systemTime += deltaTime;
		duringAdvance = true;
		l = m_runningLength;
		i = 0;
		while ((l - i) % 6 > 0)
		{
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
		}
		
		while (i < l)
		{
			// 1
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
			// 2
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
			// 3
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
			// 4
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
			// 5
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
			// 6
			tp = m_runningList[i++];
			if (m_systemTime > tp.m_goalTime)
			{
				if (tp.advance())
				{
					m_indexList[m_indexLength++] = i - 1;
				}
			}
		}

		l = m_indexLength;
		while (--l > -1)
		{
			index = m_indexList[l];
			m_runningList[index] = m_runningList[--m_runningLength];
			m_runningList.pop();
		}
		
		m_indexList.length = m_indexLength = 0;
		
		// 推进结束
		duringAdvance = false;
		
		this._checkAutoStop();
	}
	
	
	/**
	 * @inheritDoc
	 * 自动开始
	 */
	ns_despair function checkAutoStart() : void
	{
	}
	
	
	/**
	 * @inheritDoc
	 * 停止定时器
	 */
	internal function stopTimer( tp:TimerProp ) : void
	{
		var index:int;
		
		if (Boolean(tp.m_flags & TimerProp.t_runningFlag) && !duringAdvance)
		{
			index = m_runningList.indexOf(tp);
			m_runningList[index] = m_runningList[--m_runningLength];
			m_runningList.pop();
		}
		
		else if (tp.m_flags & TimerProp.t_joiningFlag)
		{
			index = m_joiningList.indexOf(tp);
			m_joiningList[index] = m_joiningList[--m_joiningLength];
			m_joiningList.pop();
		}
		
		this._checkAutoStop();
	}
	
	
	/**
	 * @inheritDoc
	 * 自动停止
	 */
	protected function _checkAutoStop() : void
	{
	}
	
	
	
	
	//======================
	// Member
	//======================
	

	ns_despair var m_timerMap:Object = { };

	ns_despair var m_numTimer:int;
	
	ns_despair var m_systemTime:Number;

	ns_despair var duringAdvance:Boolean;

	
	ns_despair var m_runningList:Vector.<TimerProp> = new Vector.<TimerProp>();

	ns_despair var m_runningLength:int;
	
	ns_despair var m_joiningList:Vector.<TimerProp> = new Vector.<TimerProp>();

	ns_despair var m_joiningLength:int;
	
	ns_despair var m_indexList:Array = [];
	
	ns_despair var m_indexLength:int;
	
	
}

}